package com.balance.anole.client.retail.service.impl;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;

import com.balance.anole.admin.to.ShopTO;
import com.balance.anole.business.to.BusinessDateTO;
import com.balance.anole.business.to.ShopPaymentTO;
import com.balance.anole.business.to.ShopReceiptPdtItemTO;
import com.balance.anole.business.to.ShopReceiptTO;
import com.balance.anole.client.retail.dao.ShopRetailDAO;
import com.balance.anole.client.retail.service.RetailService;
import com.balance.anole.client.retail.service.exception.RetailServiceException;
import com.balance.anole.client.retail.vo.RetailReceiptPrintVO;

public class RetailServiceImpl implements RetailService{

	private Logger logger = Logger.getLogger(RetailServiceImpl.class.getName());

	private ShopRetailDAO shopRetailDAO;

	public void setShopRetailDAO(ShopRetailDAO shopRetailDAO) {
		this.shopRetailDAO = shopRetailDAO;
	}

	@Override
	public List<ShopReceiptTO> getListOfHeldReceipt(String agentId) {
		return shopRetailDAO.getListOfHeldReceiptForAgent(agentId);
	}

	@Override
	public ShopReceiptTO holdReceipt(ShopReceiptTO receipt) {
		return shopRetailDAO.updateReceiptToBeHeld(receipt);
	}

	@Override
	public ShopReceiptTO releaseReceipt(ShopReceiptTO receipt) {
		return shopRetailDAO.updateReceiptToBeReleased(receipt);
	}

	private Set<ShopPaymentTO> cloneShopPaymentTO(Set<ShopPaymentTO> payments){
		Set<ShopPaymentTO> result = new HashSet<ShopPaymentTO>();
		if(payments != null){
			for(ShopPaymentTO payment : payments){
				ShopPaymentTO paymentCopy = new ShopPaymentTO();
				paymentCopy.setCreateBy(payment.getCreateBy());
				paymentCopy.setCreateDt(payment.getCreateDt());
				paymentCopy.setId(payment.getId());
				paymentCopy.setPaidValue(payment.getPaidValue());
				paymentCopy.setPaymentMode(payment.getPaymentMode());
				paymentCopy.setReceipt(payment.getReceipt());
				paymentCopy.setUpdateBy(payment.getUpdateBy());
				paymentCopy.setUpdateDt(payment.getUpdateDt());
				result.add(paymentCopy);
			}
		}
		return result;
	}

	private Set<ShopReceiptPdtItemTO> cloneShopReceiptPdtItemTO(Set<ShopReceiptPdtItemTO> pdtItems){
		Set<ShopReceiptPdtItemTO> result = new HashSet<ShopReceiptPdtItemTO>();
		if(pdtItems != null){
			for(ShopReceiptPdtItemTO pdtItem : pdtItems){
				ShopReceiptPdtItemTO pdtItemCopy = new ShopReceiptPdtItemTO();
				pdtItemCopy.setCreateBy(pdtItem.getCreateBy());
				pdtItemCopy.setCreateDt(pdtItem.getCreateDt());
				pdtItemCopy.setId(pdtItem.getId());
				pdtItemCopy.setNumOfPdtItem(pdtItem.getNumOfPdtItem());
				pdtItemCopy.setPdtItem(pdtItem.getPdtItem());
				pdtItemCopy.setReceipt(pdtItem.getReceipt());
				pdtItemCopy.setSynBusinessDate(pdtItem.getSynBusinessDate());
				pdtItemCopy.setUpdateBy(pdtItem.getUpdateBy());
				pdtItemCopy.setUpdateDt(pdtItem.getUpdateDt());
				result.add(pdtItemCopy);
			}
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	public ShopReceiptTO insertOrUpdateRetailRecord(ShopReceiptTO receipt) {
		try{
			ShopReceiptTO receipt2 = new ShopReceiptTO();
			receipt2.setId(receipt.getId());
			receipt2.setBusinessDate(receipt.getBusinessDate());
			receipt2.setCashier(receipt.getCashier());
			receipt2.setCreateBy(receipt.getCreateBy());
			receipt2.setCreateDt(receipt.getCreateDt());
			receipt2.setLineNum(receipt.getLineNum());
			receipt2.setPaymentList(cloneShopPaymentTO(receipt.getPaymentList()));
			receipt2.setProgress(receipt.getProgress());
			receipt2.setReceiptDate(receipt.getReceiptDate());
			receipt2.setReceiptNum(receipt.getReceiptNum());
			receipt2.setSeller(receipt.getSeller());
			receipt2.setShop(receipt.getShop());
			receipt2.setSynBusinessDate(receipt.getSynBusinessDate());
			receipt2.setTotalNumOfPdtItem(receipt.getTotalNumOfPdtItem());
			receipt2.setTotalPaidValue(receipt.getTotalPaidValue());
			receipt2.setTotalSoldValue(receipt.getTotalSoldValue());
			receipt2.setUpdateBy(receipt.getUpdateBy());
			receipt2.setUpdateDt(receipt.getUpdateDt());
			receipt2.setPdtItemSoldList(cloneShopReceiptPdtItemTO(receipt.getPdtItemSoldList()));
//			shopRetailDAO.insertOrUpdateRetailRecord(receipt2);


			Set<ShopReceiptPdtItemTO> l_ShopReceiptPdtItemTO = receipt2.getPdtItemSoldList();
			if(l_ShopReceiptPdtItemTO != null){
				for(Iterator<ShopReceiptPdtItemTO> it = l_ShopReceiptPdtItemTO.iterator();it.hasNext();){
					ShopReceiptPdtItemTO shopReceiptPdtItemTO = (ShopReceiptPdtItemTO)it.next();
					shopReceiptPdtItemTO.setReceipt(receipt2);
				}
//				shopRetailDAO.insertOrUpdateRetailRecord(receipt2);
			}

			Set<ShopPaymentTO> l_ShopPaymentTO = receipt2.getPaymentList();
			if(l_ShopPaymentTO != null){
				for(Iterator<ShopPaymentTO> it = l_ShopPaymentTO.iterator();it.hasNext();){
					ShopPaymentTO shopPaymentTO = (ShopPaymentTO)it.next();
					shopPaymentTO.setReceipt(receipt2);
				}
//				shopRetailDAO.insertOrUpdateRetailRecord(receipt2);
			}

			shopRetailDAO.insertOrUpdateRetailRecord(receipt2);

			return receipt2;
		}catch(Exception e){
			logger.error("保存销售信息出错", e);
			throw new RetailServiceException("保存销售信息出错",e);
		}

	}

	@Override
	public List<ShopReceiptTO> getShopReceipts4Upload(ShopTO shopTO, BusinessDateTO bizDt,
			Integer batchSize) {
		return shopRetailDAO.getShopReceipts4Upload(shopTO, bizDt, batchSize);
	}

	private void printReciept(RetailReceiptPrintVO printVO) {
		try {
			ReceiptPrintService.getInstance().print(printVO);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e);
			throw new RuntimeException("打印小票出错!", e);
		}

	}

	public void payBill(RetailReceiptPrintVO printVO, ShopReceiptTO receipt, String needPay,
			String paid, String change){
		ShopReceiptTO savedReceipt = insertOrUpdateRetailRecord(receipt);
		if(printVO != null){
			printVO.setReceiptSn(savedReceipt.getReceiptNum());

			printReciept(printVO);
		}
	}

	@Override
	public void cancelHeldReceipt(ShopReceiptTO receipt) {
		if(receipt.getId() != null && receipt.getId().intValue() != 0){
			shopRetailDAO.deleteReceipt(receipt);
		}else{
			throw new RuntimeException("receipt cannot be deleted before saved: " + receipt);
		}
	}
}
